package com.base.caselib;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.base.caselib.databinding.ActivityVcameraBinding;
import com.base.caselib.presenter.CameraPresenter;
import com.base.caselib.utils.CameraManager;
import com.base.caselib.view.CameraView;
import com.base.commonlib.base.CBaseBarMvpActivity;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;

@Route(path = "/crpuct/camera")
public class CameraActivity extends CBaseBarMvpActivity<CameraPresenter> implements SurfaceHolder.Callback , Camera.PreviewCallback ,CameraView {

    private CameraManager cameraManager;
    private static final String TAG = "CameraActivity";
    private boolean hasSurface;
    private ActivityVcameraBinding mBinding;
    boolean isStart;
    @Autowired
    String type;//1行驶证 2驾驶证 3身份证



    //训练数据路径，必须包含tesseract文件夹
    static final String TESSBASE_PATH = Environment.getExternalStorageDirectory() + "/";
    //识别语言英文
    static final String DEFAULT_LANGUAGE = "eng";

    @Override
    protected void init() {
        super.init();
        mBinding = (ActivityVcameraBinding) mRootBinding;
        mPresenter = new CameraPresenter(this,this);
        mPresenter.start();
        setBackNavigation();
        setBarTitle("识别");
    }

    @Override
    protected void start() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
        try {
            initView();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mBinding.deal.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    initView();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mBinding.bottom.setVisibility(View.GONE);
            }
        });

        mBinding.carame.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//                isStart = !isStart;
                cameraManager.takePicture(new Camera.ShutterCallback() {
                    @Override
                    public void onShutter() {

                    }
                }, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] bytes, Camera camera) {

                    }
                }, new Camera.PictureCallback() {
                    @RequiresApi(api = Build.VERSION_CODES.O)
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        bytesToImageFile(data);
                    }
                });
            }
        });
    }
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void bytesToImageFile(byte[] bytes) {

        try {
            File file = new File( Environment.getExternalStorageDirectory().getAbsolutePath() + "/lpark/park/"+System.currentTimeMillis()+".jpeg");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(bytes, 0, bytes.length);
            fos.flush();
            fos.close();
            compressBitmapToFile(file.getAbsolutePath());
            mBinding.bottom.setVisibility(View.VISIBLE);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    @RequiresApi(api = Build.VERSION_CODES.O)
    private void compressBitmapToFile(String path) {
        Bitmap bitmap = BitmapFactory.decodeFile(path);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG,100,baos);
        //图片质量小于100K不压缩(该值计算不太准)
        if( baos.toByteArray().length /1024 > 100){

            //采样压缩
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            options.inSampleSize = 1;
            BitmapFactory.decodeFile(path,options);
            //计算缩放值
            options.inSampleSize =  computeSize(options, 720, 1028);


            options.inJustDecodeBounds = false;
            bitmap = BitmapFactory.decodeFile(path,options);

            //压缩图片质量 像素值不变
            baos = new ByteArrayOutputStream();
            int options1 = 75;
            bitmap.compress(Bitmap.CompressFormat.JPEG,options1,baos);
            bitmap.recycle();
/*
        while(baos.toByteArray().length /1024 > 100){
            baos.reset();
            options1 -= 10;
            bitmap.compress(Bitmap.CompressFormat.JPEG,options1,baos);
        }*/
        }
        //将压缩后图片写入文件
        String paths = path;
        File file = new File(paths);
        if(!file.exists()){
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            String str =imageToBase64(file);
            if (type.equals("1")){
                mPresenter.getDrivLisence(str,file.getAbsolutePath());
            }else if (type.equals("2")){
                mPresenter.getDriver(str,file.getAbsolutePath());
            }else if (type.equals("3")){
                mPresenter.getCret(str,file.getAbsolutePath());
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }



    }
    private int computeSize(BitmapFactory.Options options,int reqWidth,int reqHeight) {
        int srcHeight = options.outHeight;
        int srcWidth = options.outWidth;
        srcWidth = srcWidth % 2 == 1 ? srcWidth + 1 : srcWidth;
        srcHeight = srcHeight % 2 == 1 ? srcHeight + 1 : srcHeight;

        int inSampleSize = 1;
        if (srcHeight > reqHeight || srcWidth > reqWidth) {
            final int heightRatio = Math.round((float) srcHeight / (float) reqHeight);
            final int widthRatio = Math.round((float) srcWidth / (float) reqWidth);
            inSampleSize = heightRatio <= widthRatio ? heightRatio : widthRatio;//
        }
        if (inSampleSize <= 0) {
            return 1;
        }
        return inSampleSize;

        //鲁班压缩代码
       /* int longSide = Math.max(srcWidth, srcHeight);
        int shortSide = Math.min(srcWidth, srcHeight);

        float scale = ((float) shortSide / longSide);
        if (scale <= 1 && scale > 0.5625) {
            if (longSide < 1664) {
                return 1;
            } else if (longSide >= 1664 && longSide < 4990) {
                return 2;
            } else if (longSide > 4990 && longSide < 10240) {
                return 4;
            } else {
                return longSide / 1280 == 0 ? 1 : longSide / 1280;
            }
        } else if (scale <= 0.5625 && scale > 0.5) {
            return longSide / 1280 == 0 ? 1 : longSide / 1280;
        } else {
            return (int) Math.ceil(longSide / (1280.0 / scale));
        }*/


    }













    /**
     * 图片转base64(jdk自带）
     *
     * @param file
     * @return
     * @throws IOException
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public String imageToBase64(File file) throws IOException {
        byte[] data = null;

        try {
            InputStream in = new FileInputStream(file);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            throw e;
        }

        Base64.Encoder encoder = Base64.getEncoder();

        String str = encoder.encodeToString(data);

        return str;

    }
    private void initView() throws IOException {
        SurfaceHolder surfaceHolder = mBinding.sfv.getHolder();
        if (hasSurface) {
            // activity在paused时但不会stopped,因此surface仍旧存在；
            // surfaceCreated()不会调用，因此在这里初始化camera
            initCamera(surfaceHolder);
        } else {
            // 重置callback，等待surfaceCreated()来初始化camera
            surfaceHolder.addCallback(this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cameraManager.stopPreview();
        cameraManager.closeDriver();
            SurfaceHolder surfaceHolder = mBinding.sfv.getHolder();
            surfaceHolder.removeCallback(this);

    }

    @Override
    protected int getLayoutResource() {
        return R.layout.activity_vcamera;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            initCamera(holder);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initCamera(SurfaceHolder holder) throws IOException {
        cameraManager = new CameraManager();
        if (holder == null) {
            throw new IllegalStateException("No SurfaceHolder provided");
        }
        if (cameraManager.isOpen()) {
            return;
        }
        try {
            // 打开Camera硬件设备
            cameraManager.openDriver(holder, this);
            // 创建一个handler来打开预览，并抛出一个运行时异常
            cameraManager.startPreview(this);
        } catch (Exception ioe) {
            Log.d("zk", ioe.toString());

        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        hasSurface = false;
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        camera.addCallbackBuffer(data);
        ByteArrayOutputStream baos;
        byte[] rawImage;
        Bitmap bitmap;
        Camera.Size previewSize = camera.getParameters().getPreviewSize();//获取尺寸,格式转换的时候要用到
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;
        YuvImage yuvimage = new YuvImage(
                data,
                ImageFormat.NV21,
                previewSize.width,
                previewSize.height,
                null);
        baos = new ByteArrayOutputStream();
        yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, baos);// 80--JPG图片的质量[0-100],100最高
        rawImage = baos.toByteArray();
        //将rawImage转换成bitmap
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);
        if (bitmap == null) {
            Log.d("zka", "bitmap is nlll");
            return;
        } else {
            int height = bitmap.getHeight();
            int width = bitmap.getWidth();
            final Bitmap bitmap1 = Bitmap.createBitmap(bitmap, width/2 - dip2px(150),height / 2 - dip2px(92), dip2px(300), dip2px(185));
            int x, y, w, h;
            x = (int) (bitmap1.getWidth() * 0.340);
            y = (int) (bitmap1.getHeight() * 0.800);
            w = (int) (bitmap1.getWidth() * 0.6 + 0.5f);
            h = (int) (bitmap1.getHeight() * 0.12 + 0.5f);
            Bitmap bit_hm = Bitmap.createBitmap(bitmap1, x, y, w, h);
           // iv_result.setImageBitmap(bit_hm);
            if(bit_hm != null){
                if (isStart) {
                    localre(bit_hm);
                }
            }
        }
    }


    //证件识别
    private void localre(Bitmap bm) {
//        mPresenter.getCret(mPresenter.bitmapToBase64(bm));
    }

    public int dip2px(int dp) {
        float density = this.getResources().getDisplayMetrics().density;
        return (int) (dp * density + 0.5);
    }
}
